
package cz.vse.adventura.po1715.xshet00_shevtsova.hra;
/* Soubor je ulozen v kodovani UTF-8.
 * Kontrola kódování: Příliš žluťoučký kůň úpěl ďábelské ódy. */



import cz.pecinovsky.english.pojj.adv_framework.game_gui.IBagG;
import cz.pecinovsky.english.pojj.adv_framework.game_gui.IListener;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;





/*******************************************************************************
 * Instance třídy {@code Bag} představují  Bag, místo kam se ukládá předměty
 *
 * @author    Tatyana Shevtsova
 * @version  
 */
public class Bag implements IBagG
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================

    /** Maximální kapacita batohu - v této hře dvě ruce. */
    private static final int KAPACITA = 2;


    /** Schránka na přenášené předměty. V případě této hry se ale předměty
     *  přenášejí v rukou, a proto může hráč níst současně nejvýše dva. */
    private static final Bag bag = new Bag();


//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
    private final Collection<Object> obsah = new ArrayList<Object> ();
       /** Posluchači očekávající oznámení změně předmětů v batohu. */
    private final Collection<IListener<IBagG>> posluchači =
                                       new ArrayList<IListener<IBagG>>();
    
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================


    static Bag getBag()
    {
        return bag;
    }



    /***************************************************************************
     * Vytvoří prázdný bag.
     */
    private Bag()
    {
       //stačí prázdný kontejner
       // všechno nutné je v deklaracích
    }





//== ABSTRAKTNÍ METODY =========================================================
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================


    /***************************************************************************
     * Vrátí kapacitu batohu, tj. kolik předmětů se do něj vejde.
     *
     * @return Kapacita batohu
     */
    @Override
    public int getCapacity()
    {
        return 2;
    }

    /***************************************************************************
     * Vrátí kolekci předmětů uložených v batohu.
     *
     * @return Kolekce předmětů v batohu
     */
    @Override
    public Collection<Object> getObjects()
    {
        return Collections.unmodifiableCollection(obsah);
    }


 /***************************************************************************
     * Inicializuje jedináčka a připraví jej pro novou hru.
     */
    static void inicializuj()
    {
        bag.obsah.clear();
    }


    /***************************************************************************
     * Zjistí, zda bag obsahuje předmět zadaný svým názvem.
     *
     * @param  název Název předmětu v batohu
     * @return {@code true} pokud je předmět v batohu, jinak {@code falše}
     */
    boolean obsahuje( String název ) {
        Object nasel = (Object)Utility.najdi(název, obsah);
        return (nasel != null);
    }


    /***************************************************************************
     * Přidá zadaný předmět do batohu.
     *
     * @param  předmět Předmět přidávaný do batohu
     * @return {@code true} pokud byl předmět do batohu vložen
     */

    boolean pridej( Object predmet ) {
        boolean zvedam = (obsah.size() < KAPACITA)  &&  obsah.add( predmet );
        if (zvedam) {
            obvolejPosluchače();
        }
        return zvedam;
    }


    /***************************************************************************
     * Vyjme z batohu předmět zadaný svým názvem.
     *
     * @param  název Název předmětu vybíraného z batohu
     * @return Byl-li předmět v batohu, vrátí odkaz na předmět,
     *         jinak vrátí prázdný odkaz {@code null}
     */
    Object vyjmi( String nazev ) {
        Object nasel = (Object)Utility.najdi(nazev, obsah);
        if (nasel != null) {
            obsah.remove(nasel);
            obvolejPosluchače();
        }
        return nasel;
    }


    @Override
    public String toString()  {
        return "Batoh obsahující " + obsah;
    }



    /***************************************************************************
     * Přidá zadaného posluchače do seznamu posluchačů,
     * které zpravuje o výskytu očekávané události
     *
     * @param posluchač Přihlašovaný posluchač
     */

//    @Override
    public void addListener(IListener<IBagG> posluchač)
    {
        posluchači.add(posluchač);
    }


    /***************************************************************************
     * Odebere zadaného posluchače ze seznamu posluchačů,
     * které zpravuje o výskytu očekávané události
     *
     * @param posluchač Odhlašovaný posluchač
     */
//    @Override
    public void removeListener(IListener<IBagG> posluchač)
    {
        posluchači.remove(posluchač);
    }





//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================


    /***************************************************************************
     * Obvolá všechny přihlášené posluchače, čímž jím oznámí,
     * že se obsah batohu změnil.
     */
    private void obvolejPosluchače()
    {
        for ( IListener<IBagG> posluchac : posluchači) {
            posluchac.notice(this);
        }
    }

  /***************************************************************************
     * Zjistí, zda v je batohu předmět zadaný svým názvem a vrátí jej.
     *
     * @param  název Název předmětu vybíraného z batohu
     * @return Byl-li předmět v batohu, vrátí odkaz na předmět,
     *         jinak vrátí prázdný odkaz {@code null}
     */
    private Object najdi(String název) {
        název = název.toLowerCase();
        for (Object předmět : obsah) {
            if (předmět.getName().toLowerCase().equals(název)) {
                return předmět;
            }
        }
        return null;
    }

//== VNOŘENÉ A VNITŘNÍ TŘÍDY ===================================================
//== TESTOVACÍ METODY A TŘÍDY ==================================================

}
